package com.hydra.framework.router.receiver;

import android.util.Log;

import com.hydra.framework.router.RouterIntent;

import java.util.HashMap;
import java.util.TreeSet;

import static com.hydra.framework.event.core.EventDispatcher.EVENT_LOG_TAG;

/**
 * Created by Hydra on 2017/8/3.
 *
 * 这个ReceiverList可以用TreeSet替换
 */
public class RouterReceiverList {

    private TreeSet<RouterReceiver> mReceiverClasses;

    //这个map用的是RouterReceiver里的class的hashcode当作key
    //能使用这个map的前提是在同一个url下不能有两个相同class的RouterReceiver
    private HashMap<Integer, RouterReceiver> mReceiverClassMap;

    public RouterReceiverList() {
        mReceiverClasses = new TreeSet<>(RouterReceiver.sRouterReceiverComparator);
        mReceiverClassMap = new HashMap<>();
    }

    public RouterReceiverList(RouterReceiverList from) {
        mReceiverClasses = new TreeSet<>(from.mReceiverClasses);
        mReceiverClassMap = new HashMap<>(from.mReceiverClassMap);
    }

    public void invokeToReceivers(RouterIntent eventIntent) {
        RouterReceiverList copiedReceiverList;

        synchronized (this) {
            copiedReceiverList = new RouterReceiverList(this);
        }

        for (RouterReceiver receiver : copiedReceiverList.mReceiverClasses) {
            receiver.receive(eventIntent);
        }
    }

    public synchronized void add(RouterReceiver object) {
        boolean preExist = !mReceiverClasses.add(object);

        mReceiverClassMap.put(object.getClass().hashCode(), object);

        if(preExist) {
            Log.e(EVENT_LOG_TAG, "add router destination warning, destination already exist : "
                    + object.toString());
        }
    }

    public synchronized void remove(RouterReceiver object) {
        mReceiverClasses.remove(object);
        mReceiverClassMap.remove(object.receiverClass().hashCode());
    }

    public synchronized void remove(Class<?> cls) {
        RouterReceiver routerReceiver = mReceiverClassMap.remove(cls.hashCode());

        if(routerReceiver != null) {
            mReceiverClasses.remove(routerReceiver);
        }
    }

    public synchronized int size() {
        return mReceiverClasses.size();
    }
}
